#include <bits/stdc++.h>

#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define in read<int>()
#define lin read<ll>()
#define rep(i, x, y) for(int i = (x); i <= (y); i++)
#define per(i, x, y) for(int i = (x); i >= (y); i--)

using namespace std;

using ll = long long;
using db = double;
using pii = pair < int, int >;
using vec = vector < int >;
using veg = vector < pii >;

template < typename T > T read() {
	T x = 0; bool f = 0; char ch = getchar();
	while(!isdigit(ch)) f |= ch == '-', ch = getchar();
	while(isdigit(ch)) x = x * 10 + (ch ^ 48), ch = getchar();
	return f ? -x : x;
}

template < typename T > void chkmax(T &x, const T &y) { x = x > y ? x : y; }
template < typename T > void chkmin(T &x, const T &y) { x = x < y ? x : y; }

const int inf = 0x3f3f3f3f;
const int N = 2e4 + 10;

int n, m, ch[N << 1][2], ndn, ind[N], dfn[N], indt[N << 1], tim, rt, siz[N], son[N], top[N], fa[N], dep[N], eid[N];
veg G[N];

namespace F { // max_flow
	const int N = 2e5 + 10;
	const int M = 1e7 + 10;
    int h[N], now[N], d[N], cnt = 1, S, T;
    struct edge { int v, w, nxt; } e[M << 1];
    inline void tlink(int x, int y, int w) { e[++cnt] = (edge) { y, w, h[x] }; h[x] = cnt; }
    inline void link(int x, int y, int w) { /*cerr << x << " " << y << " " << w << endl,*/ tlink(x, y, w); tlink(y, x, 0); }
    inline void setst(int s, int t) { S = s; T = t; }
    queue < int > q;
    bool bfs() {
		while(q.size()) q.pop(); q.push(S); memset(d, 0, sizeof d); d[S] = 1; now[S] = h[S];
		while(!q.empty()) {
			int x = q.front(); q.pop();
			for(int i = h[x], y; i; i = e[i].nxt)
				if(e[i].w && !d[y = e[i].v]) {
					d[y] = d[x] + 1; q.push(y); now[y] = h[y];
					if(y == T) return 1;
				}
		} return 0;
    }
    int dinic(int x,int flow) {
		if(x == T) return flow;
		int res = flow;
		for(int i = now[x],y; i && res;i = e[i].nxt) {
			now[x] = i;
			if(e[i].w && d[y = e[i].v] == d[x] + 1) {
				int k = dinic(y,min(res,e[i].w));
				if(!k) d[y] = 0; e[i].w -= k; e[i ^ 1].w += k; res -= k;
			}
		}
		return flow - res;
    }
    ll runit() {
		ll maxflow = 0,flow;
		while(bfs()) while(flow = dinic(S,inf)) maxflow += flow;
		return maxflow;
    }
	int dfn[N], bel[N], low[N], tim, scc, top, stk[N];
	bool v[N];
	void tarjan(int x) {
		low[x] = dfn[x] = ++tim; stk[++top] = x; v[x] = true;
		for(int i = h[x], y = e[i].v; i; i = e[i].nxt, y = e[i].v)
			if(e[i].w) {
				if(!dfn[y]) tarjan(y), chkmin(low[x], low[y]);
				else chkmin(low[x], dfn[y]);
			}
		if(low[x] == dfn[x]) {
			int y; ++scc;
			do {
				y = stk[top--]; v[y] = 0; bel[y] = scc;
			} while(x ^ y);
		}
	}
	void trunit() { rep(i, 0, ndn) if(!dfn[i]) tarjan(i); }
	void check(int x, vec &pot, int goal) {
		for(int i = h[x], y = e[i].v; i; i = e[i].nxt, y = e[i].v)
			if(bel[y] != bel[x]) pot.eb(y);	
	}
}

void dfs(int x, int p) {
	siz[x] = 1; fa[x] = p; dep[x] = dep[p] + 1;
	int y, id; 
	for(auto v : G[x]) {
		tie(y, id) = v;
		if(y ^ p) eid[y] = id, dfs(y, x), siz[x] += siz[y], (siz[y] > siz[son[x]]) && (son[x] = y);
	}
}

void dfs1(int x, int anc) {
	ind[dfn[x] = ++tim] = x; top[x] = anc; if(son[x]) dfs1(son[x], anc);
	for(auto y : G[x]) if(y.fi ^ fa[x] && y.fi ^ son[x]) dfs1(y.fi, y.fi);
}

void build(int &o, int l = 1, int r = n) {
	o = ++ndn; if(l == r) return indt[o] = l, void(); int mid = l + r >> 1;
	build(ch[o][0], l, mid); build(ch[o][1], mid + 1, r); F :: link(o, ch[o][0], inf); F :: link(o, ch[o][1], inf);
}

void upd(int o, int xl, int xr, int f, int l = 1, int r = n) {
	if(xl == l && xr == r) return F :: link(f, o, inf), void(); int mid = l + r >> 1;
	if(xr <= mid) upd(ch[o][0], xl, xr, f, l, mid); else if(xl > mid) upd(ch[o][1], xl, xr, f, mid + 1, r);
	else upd(ch[o][0], xl, mid, f, l, mid), upd(ch[o][1], mid + 1, xr, f, mid + 1, r);
}

void modify(int f, int x, int y) {
	while(top[x] ^ top[y]) {
		if(dep[top[x]] < dep[top[y]]) swap(x, y);
		upd(rt, dfn[top[x]], dfn[x], f); x = fa[top[x]];
	} if(dfn[x] > dfn[y]) swap(x, y); if(dfn[x] < dfn[y]) upd(rt, dfn[x] + 1, dfn[y], f);
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("1.in", "r", stdin);
#endif
	n = in, m = in;
	rep(i, 2, n) { int u = in, v = in; G[u].eb(v, i - 1); G[v].eb(u, i - 1); }
	dfs(1, 0); dfs1(1, 1); build(rt); 
	rep(i, 1, ndn) if(indt[i] > 1) F :: link(i, ndn + 1, 1);
	++ndn; F :: setst(0, ndn);
	static int tind[N * 10];
	rep(i, 1, m) {
		int x = in, y = in;
		F :: link(0, ++ndn, 1); modify(ndn, x, y);
		tind[ndn] = i;
	}
	printf("%lld\n", F :: runit());
	F :: trunit(); vec pot;
	F :: check(F :: S, pot, 0); printf("%lu ", pot.size()); for(auto v : pot) printf("%d ", tind[v]); puts(""); pot.clear(); 
	F :: check(F :: T, pot, 1); printf("%lu ", pot.size()); for(auto v : pot) printf("%d ", eid[ind[indt[v]]]); puts("");
	return 0;
}
